package org.xmlpull.v1;

import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;

public class XmlPullParserFactory {
    static final Class referenceContextClass;

    static {
        XmlPullParserFactory f = new XmlPullParserFactory();
        referenceContextClass = f.getClass();
    }

    private Hashtable features = new Hashtable();

    private boolean getFeature(String name) {
        Boolean value = (Boolean) this.features.get(name);
        return value != null && value.booleanValue();
    }

    public boolean isValidating() {
        return getFeature("http://xmlpull.org/v1/doc/features.html#validation");
    }

    public static XmlPullParserFactory newInstance()
            throws XmlPullParserException {
        return newInstance(null, null);
    }

    private static XmlPullParserFactory newInstance(String classNames, Class context)
            throws XmlPullParserException {
        if (context == null) {
            context = referenceContextClass;
        }
        String classNamesLocation;
        if ((classNames == null) || (classNames.length() == 0) || ("DEFAULT".equals(classNames))) {
            try {
                InputStream is = context.getResourceAsStream("/META-INF/services/org.xmlpull.v1.XmlPullParserFactory");
                if (is == null) {
                    throw new XmlPullParserException("resource not found: /META-INF/services/org.xmlpull.v1.XmlPullParserFactory make sure that parser implementing XmlPull API is available");
                }
                StringBuffer sb = new StringBuffer();
                for (; ; ) {
                    int ch = is.read();
                    if (ch < 0) {
                        break;
                    }
                    if (ch > 32) {
                        sb.append((char) ch);
                    }
                }
                is.close();

                classNames = sb.toString();
            } catch (Exception e) {
                throw new XmlPullParserException(null, null, e);
            }
            classNamesLocation = "resource /META-INF/services/org.xmlpull.v1.XmlPullParserFactory that contained '" + classNames + "'";
        } else {
            classNamesLocation =
                    "parameter classNames to newInstance() that contained '" + classNames + "'";
        }
        XmlPullParserFactory factory = null;
        Vector parserClasses = new Vector();
        Vector serializerClasses = new Vector();
        int pos = 0;
        while (pos < classNames.length()) {
            int cut = classNames.indexOf(',', pos);
            if (cut == -1) {
                cut = classNames.length();
            }
            String name = classNames.substring(pos, cut);

            Class candidate = null;
            Object instance = null;
            try {
                candidate = Class.forName(name);

                instance = candidate.newInstance();
            } catch (Exception ignored) {
            }
            if (candidate != null) {
                boolean recognized = false;
                if ((instance instanceof XmlPullParser)) {
                    parserClasses.addElement(candidate);
                    recognized = true;
                }
                if ((instance instanceof XmlSerializer)) {
                    serializerClasses.addElement(candidate);
                    recognized = true;
                }
                if ((instance instanceof XmlPullParserFactory)) {
                    if (factory == null) {
                        factory = (XmlPullParserFactory) instance;
                    }
                    recognized = true;
                }
                if (!recognized) {
                    throw new XmlPullParserException("incompatible class: " + name);
                }
            }
            pos = cut + 1;
        }
        if (factory == null) {
            factory = new XmlPullParserFactory();
        }
        return factory;
    }
}
